/***************************************************************************
 *                                                                         *
 * Copyright (c) 2007 - 2009 Nuvoton Technology Corp. All rights reserved.*
 *                                                                         *
 ***************************************************************************/
 

#ifdef ECOS
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "drv_api.h"
#include "diag.h"
#include "wbio.h"
#include "NUC900_GE.h"
#include "NUC900_GE_Regs.h"
#include "NUC900_reg.h"
#else
#include <stdio.h>
#include "NUC900_GE.h"
#include "NUC900_GE_Regs.h"
#include "wbio.h"
#ifdef _NUC900_
#include "NUC900_reg.h"
#else
#include "reg702.h"
#endif
#endif


///////////////////////////////////////////////////////////////////////////////
//
// Function: color_expansion_blt()
//
// Description:
//   OffScreen-to-OnScreen TextBLT. 
//   Fetch the monochrome source data from off-screen memory to the desired
//   destination area
///////////////////////////////////////////////////////////////////////////////
/*
** Color Expansion BLT has the following problems:
** - The mono source data must from SDRAM, not data port.
** - Source pitch and destination pitch must be the same.
** - If the pitch size is 640, the command will not complete.
**
*/
void color_expansion_blt(int x, int y, int width, int height, int fore_color, int back_color, int opt, void *buf)
{
  UINT32 cmd32, dest_pitch, src_pitch, pitch, dest_start, dest_dimension;
  UINT32 fore_color32, back_color32;
  UINT32 new_dest_start_addr;

#ifdef DEBUG 
  printf("color_expansion_blt()\n");
  printf("(%d,%d)-(%d,%d)\n", x, y, x+width-1, y+height-1);
  printf("draw mode=%d\n", opt);
#endif
    
  fore_color32 = make_color(fore_color);
  back_color32 = make_color(back_color);
  
  cmd32 = 0xcc430080; 
  if (opt==MODE_TRANSPARENT)
  {
    cmd32 |= 0x00004000; // mono transparency
  }
  
  outpw(REG_2D_GEC, cmd32);

  outpw(REG_2D_GEFC, fore_color32);
  outpw(REG_2D_GEBC, back_color32);
  
  dest_pitch = GFX_WIDTH; // pitch in pixels
  src_pitch = width; // pitch in pixels
  
  pitch = (dest_pitch << 16) | src_pitch;
  outpw(REG_2D_GESDP, pitch);
  
  outpw(REG_2D_GEXYSORG, (int)buf);
  outpw(REG_2D_GESSXYL, 0); // always start from (0,0)
 
 #if 0 // test with changing source start address
   /*
   ** Old hardware will rotate the mono bitmap. Software must correct it.
   */
   dest_start = y << 16;
   outpw(REG_2D_GEDSXYL, dest_start);
   new_dest_start_addr = GFX_START_ADDR + x * (GFX_BPP/8);
   outpw(REG_2D_GEXYDORG, new_dest_start_addr);
 #else
  dest_start = y << 16 | x;
  outpw(REG_2D_GEDSXYL, dest_start);
#endif
  
  dest_dimension = height << 16 | width;
  outpw(REG_2D_GEDIXYL, dest_dimension);
  
  if (_ClipEnable)
  {
    cmd32 |= 0x00000200;
    if (_OutsideClip)
    {
      cmd32 |= 0x00000100;
    }
    outpw(REG_2D_GEC, cmd32);
    outpw(REG_2D_GECBTL, _ClipTL);
    outpw(REG_2D_GECBBR, _ClipBR);
  }  
  
  outpw(REG_2D_GETG, 1); 
  
  while ((inpw(REG_2D_GEINTS)&0x01)==0); // wait for command complete  

  outpw(REG_2D_GEINTS, 1); // clear interrupt status
}


///////////////////////////////////////////////////////////////////////////////
//
// Function: host_color_expansion_blt()
//
// Description:
//   Host-to-Screen TextBLT through data port. 
//
///////////////////////////////////////////////////////////////////////////////
void host_color_expansion_blt(int x, int y, int width, int height, int fore_color, int back_color, int opt, void *buf)
{
  UINT32 cmd32, dest_pitch, dest_start, dest_dimension;
  UINT32 fore_color32, back_color32;
  UINT32 *ptr32, data32;
  int transfer_count, i, j;

#ifdef DEBUG   
  //printf("host_color_expansion_blt()\n");
  //printf("(%d,%d)-(%d,%d)\n", x, y, x+width-1, y+height-1);
  //printf("draw mode=%d\n", opt);
#endif   
 
  fore_color32 = make_color(fore_color);
  //printf("fore_color32= %lx\n", fore_color32);
  back_color32 = make_color(back_color);
  //printf("back_color32= %lx\n", back_color32);
  
  cmd32 = 0xcc4300a0; 
  //cmd32 = 0xcc430020;  // smf
  if (opt==MODE_TRANSPARENT)
  {
    cmd32 |= 0x00004000; // mono transparency
  }
  
  outpw(REG_2D_GEC, cmd32);

  outpw(REG_2D_GEFC, fore_color32);
  outpw(REG_2D_GEBC, back_color32);
  
  dest_pitch = GFX_WIDTH << 16; // pitch in pixel
  outpw(REG_2D_GESDP, dest_pitch);
  
  dest_start = y << 16 | x;
  outpw(REG_2D_GEDSXYL, dest_start);
  outpw(REG_2D_GESSXYL, dest_start);
  
  dest_dimension = height << 16 | width;
  outpw(REG_2D_GEDIXYL, dest_dimension);  
  
  outpw(REG_2D_GETG, 1); 
  
  ptr32 = (UINT32 *)buf;
  for (i=0; i<height; i++)
  {
    transfer_count = (width+31) / 32; // 32 pixels unit
    //transfer_count = (width * (GFX_BPP/8) + 3) / 4; // 4-byte count
  
    while (transfer_count > 8)
    {
      while ((inpw(REG_2D_GEMC) & 0x00000800)==0); // check empty
      for (j=0; j<8; j++) 
      {
        data32 = *ptr32++;
        outpw(REG_2D_GEHBDW0, data32);
      }
      transfer_count -= 8;
    }
    
    if (transfer_count > 0)
    {
      while ((inpw(REG_2D_GEMC) & 0x00000800)==0); // check empty
      for (j=0; j<transfer_count; j++) 
      {
        data32 = *ptr32++;
        outpw(REG_2D_GEHBDW0, data32);
      } 
    }   
  }
  
  while ((inpw(REG_2D_GEINTS)&0x01)==0); // wait for command complete  

  outpw(REG_2D_GEINTS, 1); // clear interrupt status
}



